package main

import (
    "fmt"
    "net"
    "time"
)

func main() {
    go startMaster()
    go startSlave()

    fmt.Println("Master and Slave started. Press Ctrl+C to exit.")
    
    // 新增：初始化完成后上报
    reportInitializationComplete()

    select {}
}

// 新增函数：上报初始化完成
func reportInitializationComplete() {
    conn, err := net.Dial("tcp", config.SlaveAddr)
    if err != nil {
        fmt.Println("Error connecting to slave for initialization report:", err)
        return
    }
    defer conn.Close()

    timestamp := time.Now().Format(time.RFC3339) // 记录时间戳
    message := fmt.Sprintf("[%s] Initialization complete", timestamp)
    sendIEC104Message(conn, IEC104Message{Type: "I", Data: message, AuthKey: generateAuthKey(message, config.AuthKey)})
    fmt.Println("Initialization completion reported:", message)
}

// 新增函数：发送带时标CP56Time2a的测试命令
func sendTimestampedTestCommand(conn net.Conn) {
    timestamp := time.Now().Format("2006-01-02 15:04:05")
    message := fmt.Sprintf("Test command at %s", timestamp)
    sendIEC104Message(conn, IEC104Message{Type: "TS", Data: message, AuthKey: generateAuthKey(message, config.AuthKey)})
    fmt.Println("Timestamped test command sent:", message)
}

// 新增函数：发送文件传输请求
func sendFileTransferRequest(conn net.Conn, fileName string) {
    timestamp := time.Now().Format(time.RFC3339)
    message := fmt.Sprintf("File transfer request for %s at %s", fileName, timestamp)
    sendIEC104Message(conn, IEC104Message{Type: "FILE", Data: fileName, AuthKey: generateAuthKey(message, config.AuthKey)})
    fmt.Println("File transfer request sent:", message)
}

// 新增函数：接收文件数据
func receiveFileData(conn net.Conn) {
    for {
        message, err := receiveIEC104Message(conn)
        if err != nil {
            fmt.Println("Error receiving file data:", err)
            return
        }

        if message.Type == "DATA" {
            timestamp := time.Now().Format(time.RFC3339)
            fmt.Printf("[%s] Received file data: %s\n", timestamp, message.Data)
            // 这里可以添加实际的文件数据处理逻辑
        }
    }
}

func startMaster() {
    listener, err := net.Listen("tcp", config.MasterAddr)
    if err != nil {
        fmt.Println("Error starting master:", err)
        return
    }
    defer listener.Close()

    fmt.Println("Master started on", config.MasterAddr)

    for {
        conn, err := listener.Accept()
        if err != nil {
            fmt.Println("Error accepting connection:", err)
            continue
        }
        go handleMasterConnection(conn)
    }
}

func handleMasterConnection(conn net.Conn) {
    defer conn.Close()

    for {
        message, err := receiveIEC104Message(conn)
        if err != nil {
            fmt.Println("Error receiving message:", err)
            return
        }

        if !verifyAuthKey(message.Data, config.AuthKey, message.AuthKey) {
            fmt.Println("Authentication failed")
            return
        }

        timestamp := time.Now().Format(time.RFC3339)
        switch message.Type {
        case "C":
            fmt.Printf("[%s] Data call: %s\n", timestamp, message.Data)
            sendIEC104Message(conn, IEC104Message{Type: "R", Data: "01", AuthKey: generateAuthKey("01", config.AuthKey)})
        case "R":
            fmt.Printf("[%s] Remote control: %s\n", timestamp, message.Data)
            sendIEC104Message(conn, IEC104Message{Type: "A", Data: "02", AuthKey: generateAuthKey("02", config.AuthKey)})
        case "A":
            fmt.Printf("[%s] Remote adjustment: %s\n", timestamp, message.Data)
            sendIEC104Message(conn, IEC104Message{Type: "S", Data: "03", AuthKey: generateAuthKey("03", config.AuthKey)})
        case "S":
            fmt.Printf("[%s] Remote signal: %s\n", timestamp, message.Data)
            sendIEC104Message(conn, IEC104Message{Type: "M", Data: "04", AuthKey: generateAuthKey("04", config.AuthKey)})
        case "M":
            fmt.Printf("[%s] Remote measurement: %s\n", timestamp, message.Data)
            sendIEC104Message(conn, IEC104Message{Type: "F", Data: "05", AuthKey: generateAuthKey("05", config.AuthKey)})
        case "G": // 处理总召唤命令
            handleGeneralInterrogation(conn, message.Data)
        case "PULSE": // 处理电能脉冲召唤命令
            handlePulseInterrogation(conn, message.Data)
        case "T": // 处理时钟同步命令
            handleClockSynchronization(conn, message.Data)
        case "RESET": // 处理复位进程命令
            handleResetProcess(conn, message.Data)
        case "TS": // 处理带时标CP56Time2a的测试命令
            fmt.Printf("[%s] Timestamped test command received: %s\n", timestamp, message.Data)
            sendIEC104Message(conn, IEC104Message{Type: "TS", Data: "00", AuthKey: generateAuthKey("00", config.AuthKey)})
        case "FILE": // 处理文件传输请求
            fmt.Printf("[%s] File transfer request received: %s\n", timestamp, message.Data)
            sendFileData(conn, message.Data)
        default:
            fmt.Printf("[%s] Unknown message type: %s\n", timestamp, message.Type)
        }
    }
}

// 新增函数：处理复位进程命令
func handleResetProcess(conn net.Conn, command string) {
    fmt.Printf("Handling reset process command: %s\n", command)
    // 这里可以添加实际的复位进程命令处理逻辑
    sendIEC104Message(conn, IEC104Message{Type: "RESET", Data: "00", AuthKey: generateAuthKey("00", config.AuthKey)})
}

// 新增函数：处理时钟同步命令
func handleClockSynchronization(conn net.Conn, command string) {
    fmt.Printf("Handling clock synchronization command: %s\n", command)
    // 这里可以添加实际的时钟同步命令处理逻辑
    sendIEC104Message(conn, IEC104Message{Type: "T", Data: "00", AuthKey: generateAuthKey("00", config.AuthKey)})
}

// 新增函数：处理总召唤命令
func handleGeneralInterrogation(conn net.Conn, command string) {
    fmt.Printf("Handling general interrogation command: %s\n", command)
    // 这里可以添加实际的总召唤命令处理逻辑
    sendIEC104Message(conn, IEC104Message{Type: "G", Data: "00", AuthKey: generateAuthKey("00", config.AuthKey)})
}

// 新增函数：处理电能脉冲召唤命令
func handlePulseInterrogation(conn net.Conn, command string) {
    fmt.Printf("Handling pulse interrogation command: %s\n", command)
    // 这里可以添加实际的电能脉冲召唤命令处理逻辑
    sendIEC104Message(conn, IEC104Message{Type: "PULSE", Data: "00", AuthKey: generateAuthKey("00", config.AuthKey)})
}

func startSlave() {
    conn, err := net.Dial("tcp", "localhost:8080")
    if err != nil {
        fmt.Println("Slave: Error connecting to master:", err)
        return
    }
    defer conn.Close()

    fmt.Println("Slave: Connected to master")

    buffer := make([]byte, 1024)
    for {
        n, err := conn.Read(buffer)
        if err != nil {
            fmt.Println("Slave: Error reading message:", err)
            return
        }

        message := string(buffer[:n])
        fmt.Println("Slave: Received message:", message)
    }
}